{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 203Agent Openai Assistants\n",
    "Assistants API 允许您在自己的应用程序中构建 AI 助手。\n",
    "\n",
    "您可以使用 OpenAI 工具或自定义工具与 OpenAI 助手进行交互。当专门使用 OpenAI 工具时，您只需直接调用助手即可获得最终答案。使用自定义工具时，您可以使用内置的 AgentExecutor 运行助手和工具执行循环，也可以轻松编写自己的执行器。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "#设置代理\n",
    "import os\n",
    "\n",
    "os.environ['http_proxy'] = 'http://127.0.0.1:10809'\n",
    "os.environ['https_proxy'] = 'http://127.0.0.1:10809'\n",
    "\n",
    "# 这里我们需要用到google的搜索api\n",
    "# 在这个网址https://serpapi.com/search-api，但是需要你用邮箱验证和手机号验证\n",
    "os.environ[\"SERPAPI_API_KEY\"] = \"5266d1ac4xxxxxxxxxxxxxxx91\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[ThreadMessage(id='msg_fAMj9oaH1Tz7JtSVv2evKWpF', assistant_id='asst_rjIhBCEKyIYq5GKmg1UhMdxZ', content=[MessageContentText(text=Text(annotations=[], value='10 - 4 的结果是 6，与 2.7 相比提高了大约 122.22%。'), type='text')], created_at=1703828765, file_ids=[], metadata={}, object='thread.message', role='assistant', run_id='run_pmFLgqS6mGGVdDsRteayDWgY', thread_id='thread_0yIF1UlI0N4sZHh6uOH7xCzx')]"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from langchain.agents.openai_assistant import OpenAIAssistantRunnable\n",
    "interpreter_assistant = OpenAIAssistantRunnable.create_assistant(\n",
    "    name=\"langchain assistant\",\n",
    "    instructions=\"你是一名私人数学辅导员。编写并运行代码来回答数学问题。\",\n",
    "    tools=[{\"type\": \"code_interpreter\"}],\n",
    "    model=\"gpt-4-1106-preview\",\n",
    ")\n",
    "output = interpreter_assistant.invoke({\"content\": \"10 - 4 与 2.7 相比提高了多少？\"})\n",
    "output"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 使用OpenAI functions\n",
    "某些 OpenAI 模型（如 gpt-3.5-turbo-0613 和 gpt-4-0613）已经过微调，可以检测何时应该调用函数，并使用应传递给函数的输入进行响应。在 API 调用中，您可以描述函数，并让模型智能地选择输出包含参数的 JSON 对象来调用这些函数。OpenAI 函数 API 的目标是比通用文本完成或聊天 API 更可靠地返回有效且有用的函数调用。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Requirement already satisfied: openai in c:\\users\\administrator\\desktop\\codeproject\\langchainstudy\\.venv\\lib\\site-packages (1.6.0)\n",
      "Requirement already satisfied: google-search-results in c:\\users\\administrator\\desktop\\codeproject\\langchainstudy\\.venv\\lib\\site-packages (2.4.2)\n",
      "Requirement already satisfied: anyio<5,>=3.5.0 in c:\\users\\administrator\\desktop\\codeproject\\langchainstudy\\.venv\\lib\\site-packages (from openai) (3.7.1)\n",
      "Requirement already satisfied: distro<2,>=1.7.0 in c:\\users\\administrator\\desktop\\codeproject\\langchainstudy\\.venv\\lib\\site-packages (from openai) (1.8.0)\n",
      "Requirement already satisfied: httpx<1,>=0.23.0 in c:\\users\\administrator\\desktop\\codeproject\\langchainstudy\\.venv\\lib\\site-packages (from openai) (0.26.0)\n",
      "Requirement already satisfied: pydantic<3,>=1.9.0 in c:\\users\\administrator\\desktop\\codeproject\\langchainstudy\\.venv\\lib\\site-packages (from openai) (2.5.2)\n",
      "Requirement already satisfied: sniffio in c:\\users\\administrator\\desktop\\codeproject\\langchainstudy\\.venv\\lib\\site-packages (from openai) (1.3.0)\n",
      "Requirement already satisfied: tqdm>4 in c:\\users\\administrator\\desktop\\codeproject\\langchainstudy\\.venv\\lib\\site-packages (from openai) (4.66.1)\n",
      "Requirement already satisfied: typing-extensions<5,>=4.7 in c:\\users\\administrator\\desktop\\codeproject\\langchainstudy\\.venv\\lib\\site-packages (from openai) (4.9.0)\n",
      "Requirement already satisfied: requests in c:\\users\\administrator\\desktop\\codeproject\\langchainstudy\\.venv\\lib\\site-packages (from google-search-results) (2.31.0)\n",
      "Requirement already satisfied: idna>=2.8 in c:\\users\\administrator\\desktop\\codeproject\\langchainstudy\\.venv\\lib\\site-packages (from anyio<5,>=3.5.0->openai) (3.6)\n",
      "Requirement already satisfied: exceptiongroup in c:\\users\\administrator\\desktop\\codeproject\\langchainstudy\\.venv\\lib\\site-packages (from anyio<5,>=3.5.0->openai) (1.2.0)\n",
      "Requirement already satisfied: certifi in c:\\users\\administrator\\desktop\\codeproject\\langchainstudy\\.venv\\lib\\site-packages (from httpx<1,>=0.23.0->openai) (2023.11.17)\n",
      "Requirement already satisfied: httpcore==1.* in c:\\users\\administrator\\desktop\\codeproject\\langchainstudy\\.venv\\lib\\site-packages (from httpx<1,>=0.23.0->openai) (1.0.2)\n",
      "Requirement already satisfied: h11<0.15,>=0.13 in c:\\users\\administrator\\desktop\\codeproject\\langchainstudy\\.venv\\lib\\site-packages (from httpcore==1.*->httpx<1,>=0.23.0->openai) (0.14.0)\n",
      "Requirement already satisfied: annotated-types>=0.4.0 in c:\\users\\administrator\\desktop\\codeproject\\langchainstudy\\.venv\\lib\\site-packages (from pydantic<3,>=1.9.0->openai) (0.6.0)\n",
      "Requirement already satisfied: pydantic-core==2.14.5 in c:\\users\\administrator\\desktop\\codeproject\\langchainstudy\\.venv\\lib\\site-packages (from pydantic<3,>=1.9.0->openai) (2.14.5)\n",
      "Requirement already satisfied: colorama in c:\\users\\administrator\\desktop\\codeproject\\langchainstudy\\.venv\\lib\\site-packages (from tqdm>4->openai) (0.4.6)\n",
      "Requirement already satisfied: charset-normalizer<4,>=2 in c:\\users\\administrator\\desktop\\codeproject\\langchainstudy\\.venv\\lib\\site-packages (from requests->google-search-results) (3.3.2)\n",
      "Requirement already satisfied: urllib3<3,>=1.21.1 in c:\\users\\administrator\\desktop\\codeproject\\langchainstudy\\.venv\\lib\\site-packages (from requests->google-search-results) (2.1.0)\n"
     ]
    }
   ],
   "source": [
    "! pip install openai google-search-results"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 初始化工具"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Collecting numexpr\n",
      "  Downloading numexpr-2.8.8-cp310-cp310-win_amd64.whl.metadata (8.1 kB)\n",
      "Requirement already satisfied: numpy>=1.13.3 in c:\\users\\administrator\\desktop\\codeproject\\langchainstudy\\.venv\\lib\\site-packages (from numexpr) (1.26.2)\n",
      "Downloading numexpr-2.8.8-cp310-cp310-win_amd64.whl (96 kB)\n",
      "   ---------------------------------------- 0.0/96.4 kB ? eta -:--:--\n",
      "   ---------------------------------------- 0.0/96.4 kB ? eta -:--:--\n",
      "   ---------------------------------------- 0.0/96.4 kB ? eta -:--:--\n",
      "   ---- ----------------------------------- 10.2/96.4 kB ? eta -:--:--\n",
      "   ---- ----------------------------------- 10.2/96.4 kB ? eta -:--:--\n",
      "   ---- ----------------------------------- 10.2/96.4 kB ? eta -:--:--\n",
      "   ------------ --------------------------- 30.7/96.4 kB 146.3 kB/s eta 0:00:01\n",
      "   ---------------- ----------------------- 41.0/96.4 kB 140.9 kB/s eta 0:00:01\n",
      "   ---------------- ----------------------- 41.0/96.4 kB 140.9 kB/s eta 0:00:01\n",
      "   ---------------- ----------------------- 41.0/96.4 kB 140.9 kB/s eta 0:00:01\n",
      "   ---------------- ----------------------- 41.0/96.4 kB 140.9 kB/s eta 0:00:01\n",
      "   ---------------- ----------------------- 41.0/96.4 kB 140.9 kB/s eta 0:00:01\n",
      "   ------------------------- -------------- 61.4/96.4 kB 109.4 kB/s eta 0:00:01\n",
      "   -------------------------------------- - 92.2/96.4 kB 159.1 kB/s eta 0:00:01\n",
      "   ---------------------------------------- 96.4/96.4 kB 167.3 kB/s eta 0:00:00\n",
      "Installing collected packages: numexpr\n",
      "Successfully installed numexpr-2.8.8\n"
     ]
    }
   ],
   "source": [
    "! pip install numexpr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "from langchain.agents import AgentType, Tool, initialize_agent\n",
    "from langchain.chains import LLMMathChain\n",
    "from langchain.chat_models import ChatOpenAI\n",
    "from langchain.utilities import SerpAPIWrapper, SQLDatabase\n",
    "\n",
    "llm = ChatOpenAI(temperature=0, model=\"gpt-3.5-turbo-0613\")\n",
    "search = SerpAPIWrapper()\n",
    "llm_math_chain = LLMMathChain.from_llm(llm=llm, verbose=True)\n",
    "\n",
    "tools = [\n",
    "    Tool(\n",
    "        name=\"Search\",\n",
    "        func=search.run,\n",
    "        description=\"useful for when you need to answer questions about current events. You should ask targeted questions\",\n",
    "    ),\n",
    "    Tool(\n",
    "        name=\"Calculator\",\n",
    "        func=llm_math_chain.run,\n",
    "        description=\"useful for when you need to answer questions about math\",\n",
    "    ),\n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder\n",
    "prompt = ChatPromptTemplate.from_messages(\n",
    "    [\n",
    "        (\"system\", \"You are a helpful assistant\"),\n",
    "        (\"user\", \"{input}\"),\n",
    "        MessagesPlaceholder(variable_name=\"agent_scratchpad\"),\n",
    "    ]\n",
    ")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.tools.render import format_tool_to_openai_function\n",
    "llm_with_tools = llm.bind(functions=[format_tool_to_openai_function(t) for t in tools])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.agents.format_scratchpad import format_to_openai_function_messages\n",
    "from langchain.agents.output_parsers import OpenAIFunctionsAgentOutputParser\n",
    "agent = (\n",
    "    {\n",
    "        \"input\": lambda x: x[\"input\"],\n",
    "        \"agent_scratchpad\": lambda x: format_to_openai_function_messages(\n",
    "            x[\"intermediate_steps\"]\n",
    "        ),\n",
    "    }\n",
    "    | prompt\n",
    "    | llm_with_tools\n",
    "    | OpenAIFunctionsAgentOutputParser()\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3m\n",
      "Invoking: `Search` with `吴京的老婆`\n",
      "\n",
      "\n",
      "\u001b[0m\u001b[36;1m\u001b[1;3mXie Nan\u001b[0m\u001b[32;1m\u001b[1;3m\n",
      "Invoking: `Search` with `吴京的老婆谢楠年龄`\n",
      "\n",
      "\n",
      "\u001b[0m\u001b[36;1m\u001b[1;3m吴京谢楠年龄差是多少九岁可是有相当大的代沟了_平平... 2022年5月31日据两人资料显示,谢楠生于1983年,吴京生于1974年,这样算来,谢楠吴京相差9岁。\u001b[0m\u001b[32;1m\u001b[1;3m吴京的妻子是谢楠，她的年龄是1983年出生的，目前大约是39岁。\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'input': '谁是吴京的老婆？她现在的年龄是多少？', 'output': '吴京的妻子是谢楠，她的年龄是1983年出生的，目前大约是39岁。'}"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from langchain.agents import AgentExecutor\n",
    "agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)\n",
    "agent_executor.invoke(\n",
    "    {\n",
    "        \"input\": \"谁是吴京的老婆？她现在的年龄是多少？\"\n",
    "    }\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 直接使用 OpenAIFunctionsAgent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "agent_executor = initialize_agent(\n",
    "    tools, llm, agent=AgentType.OPENAI_FUNCTIONS, verbose=True\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3m\n",
      "Invoking: `Search` with `吴京的老婆`\n",
      "\n",
      "\n",
      "\u001b[0m\u001b[36;1m\u001b[1;3m[\"Xie Nan (谢楠) type: Chinese actor ‧ Wu Jing's wife.\", 'Xie Nan (谢楠) born: 1983 (age 40 years), Hefei, China.', 'Xie Nan (谢楠) spouse: Wu Jing (m. 2013).', 'Xie Nan (谢楠) tv_shows: Healing Master, Snow Day.', 'Xie Nan (谢楠) nationality: Chinese.', 'Xie Nan (谢楠) grandchildren: Wu Zhi, Wu Ying.', '吴京老婆晒儿子做披萨，粉丝却把关注点放在脚上：遗传基因强大！ 丫丫健康美食 10.', '而作为最大的赢家吴京更是为了宣传电影，常常请别人吃饭，导致身材大走样，让不少人觉得战狼成了灰太狼的既视感！ 吴京最成功的不是他拍摄的电影，而是娶了一位好老婆，吴京在不出名的时候就将已是知名主持人的谢楠娶回了家，而得知吴京要拍电影，谢楠更是义无反顾的支持着吴京！ 也让吴京在战狼1的时候有 ...', '吴京有几任老婆- 百度 吴京\\ue641目前只有一任老婆 ，她的名字是谢楠\\ue641。 吴京和谢楠是在2014年结婚的，他们的两个孩子分别是吴所谓，出生于2014年，和吴虑，出生于2018年。 搜索结果中提到的其他女性，如樊亦敏和兰玉，并不是吴京的第一任或现任妻子，因此这部分信息是错误的。', '吴京还在婚礼上公开承认爱妻谢楠已怀有身孕，如今一家三口十分美满。而吴京在婚前因为受伤而影响活动，尽管身体稍有不适，但全程依然是甜蜜蜜的。', '#谢楠，83年11月6日出生于安徽省合肥，毕业于安徽财经大学，中国内地女主持人、演员，娱乐圈公认的“旺夫”女星，吴京背后的女人 · @ 高清影视混剪.', '吴京老婆谢楠二胎产子，无虑同学闪亮登场，网友：这手势很六哦！ 照片中，一家四口的拳头给人一种温馨感，而在细节上不得不说吴京谢楠夫妇做得十分 ...', '视频里两人夜里在街上漫步，吴京整个人都挂在老婆身上，像个人形挂件一样。 吴京和谢楠结婚已经9年了，这些年来，两人出圈要不就是获奖，要不就是秀恩爱 ...', '8月31日，吴京老婆谢楠在个人社交平台晒出一段视频分享家庭日常，她还附文写道：“今天也是兄友弟恭的一天呢”，言语中满是欣慰。 再看谢楠分享的视频，谢楠镜头下两个儿子一身居家装出镜，只见老大吴所谓正在耐心教着小4岁的弟弟如何跑步。', '6月5日晚，吴京老婆谢楠在个人社交平台分享出一张母子温馨合照，她还附文写道：“知道我紫外线过敏，吴所谓努力给我遮太阳，其实我明明穿了防晒衣”， ...']\u001b[0m\u001b[32;1m\u001b[1;3m吴京的老婆是谢楠（Xie Nan）。她现在的年龄是40岁（出生于1983年）。\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'input': '谁是吴京的老婆？她现在的年龄是多少？',\n",
       " 'output': '吴京的老婆是谢楠（Xie Nan）。她现在的年龄是40岁（出生于1983年）。'}"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "agent_executor.invoke(\n",
    "    {\n",
    "        \"input\": \"谁是吴京的老婆？她现在的年龄是多少？\"\n",
    "    }\n",
    ")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
